package com.base.service;

import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.digest.BCrypt;
import cn.hutool.jwt.JWTUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.base.common.LoginBody;
import com.base.common.RedisCache;
import com.base.constant.Constants;
import com.base.domain.*;
import com.base.enums.DeletedEnum;
import com.base.enums.StatusEnum;
import com.base.mapper.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * @author gxd
 * @since 2025/6/8
 */

@Service
public class LoginService {

    @Autowired
    private SysUserMapper userMapper;

    @Autowired
    private SysRoleMapper roleMapper;

    @Autowired
    private SysUserRoleMapper userRoleMapper;

    @Autowired
    private SysMenuMapper menuMapper;

    @Autowired
    private SysRoleMenuMapper roleMenuMapper;

    @Autowired
    private RedisCache redisCache;

    /**
     * 登录方法
     * @param loginBody 登录参数
     * @return token
     */
    public Map<String, Object> login(LoginBody loginBody) throws Exception {
        String username = loginBody.getUsername();
        String password = loginBody.getPassword();

        // 校验登录用户
        SysUser sysUser = userMapper.selectOne(Wrappers.lambdaQuery(SysUser.class).eq(SysUser::getUsername, username));
        if (ObjUtil.isNull(sysUser)) {
            throw new Exception("用户不存在");
        }

        // 校验登录密码
        boolean isValid = BCrypt.checkpw(password, sysUser.getPassword());
        if (!isValid) {
            throw new Exception("密码不正确");
        }

        // 获取当前用户角色
        List<Long> roleIds = userRoleMapper.selectList(
                Wrappers.lambdaQuery(SysUserRole.class).eq(SysUserRole::getUserId, sysUser.getId())
        ).stream().map(SysUserRole::getRoleId).collect(Collectors.toList());

        List<SysRole> sysRoles = !roleIds.isEmpty() ?
                roleMapper.selectList(
                        Wrappers.lambdaQuery(SysRole.class).in(SysRole::getId, roleIds)
                ) : Collections.emptyList();

        sysUser.setRoleList(sysRoles);


        // 获取当前用户权限
        Set<String> permissions = new HashSet<>();
        if (sysUser.isAdmin()) {
            permissions.add(Constants.All_PERMISSION);
        } else if (!roleIds.isEmpty()) {
            List<Long> menuIds = roleMenuMapper.selectList(
                    Wrappers.lambdaQuery(SysRoleMenu.class).in(SysRoleMenu::getRoleId, roleIds)
            ).stream().map(SysRoleMenu::getMenuId).collect(Collectors.toList());

            if (!menuIds.isEmpty()) {
                permissions = menuMapper.selectList(
                                Wrappers.lambdaQuery(SysMenu.class)
                                        .in(SysMenu::getId, menuIds)
                                        .eq(SysMenu::getDeleted, DeletedEnum.NO.getCode())
                                        .eq(SysMenu::getStatus, StatusEnum.OK.getCode())
                        ).stream()
                        .map(SysMenu::getPermission)
                        .filter(StrUtil::isNotBlank)
                        .collect(Collectors.toSet());
            }
        }
        sysUser.setPermissions(permissions);

        // 自定义负载（claims）
        Map<String, Object> userMap = new HashMap<>();
        userMap.put("userid", sysUser.getId());
        userMap.put("username", username);
        // 生成token
        String token = JWTUtil.createToken(userMap, Constants.SECRET_KEY.getBytes());

        // 把登录信息存入redis
        redisCache.setCacheObject(Constants.LOGIN_TOKEN_KEY + token, sysUser, 30, TimeUnit.MINUTES);

        Map<String, Object> result = new HashMap<>();
        result.put(Constants.TOKEN, token);
        return result;
    }
}
